//
// Created by Max on 2025/5/28.
//

#include "MicThread.h"

MicThread *MicThread::s_pMicThread = nullptr;
std::mutex MicThread::s_Mutex;
static std::string filePath = "/storage/emulated/0/recorder";

static const char *SAVE_FILE_KEY = "haier.tv.save.mic.file";
static const char *TAG = "MicThread";
static const std::string wavFile = filePath + "/haier.wav";
static const std::string pcmFile = filePath + "/haier.pcm";
static const char *MIC_PROP_KEY = "vendor.haier.mic.num";

MicThread::MicThread() : TvThread(nullptr, nullptr,this),m_pMtkConfig(nullptr),m_pSaveWav(nullptr),m_bIsMicThreadRunning(
        false){

}

MicThread::~MicThread() {

}

MicThread *MicThread::getInstance() {
    s_Mutex.lock();
    if (s_pMicThread == nullptr) {
        s_pMicThread = new MicThread();
    }
    s_Mutex.unlock();
    return s_pMicThread;
}

int MicThread::Init(int chanelNum, int sampleRate) {

    if (m_pMtkConfig == nullptr) {
        m_pMtkConfig = new MicConfig();
    }

    LOGD("MicThread  MicThread Init");
    if (m_pMtkConfig->Init(chanelNum,sampleRate) != MI_SUCCESS) {
        LOGE("m_pMtkMicConfig->Init() failed");
        return MI_FAILURE;
    }

    LOGD("m_pMtkConfig  m_pMtkConfig Init Success");

    if (m_pSaveWav == nullptr) {
        m_pSaveWav = new SaveWav(chanelNum, sampleRate, PCM_FORMAT_S16_LE);
        m_pSaveWav->openFile(filePath);
        m_pSaveWav->fSeekAfterWavHeader();
    }
    mBufferSize = m_pMtkConfig->pcmFrames2Bytes(m_pMtkConfig->pcmGetBufferSize());
    LOGD("pcmGetBufferSize === %d", m_pMtkConfig->pcmGetBufferSize());
    LOGD("mBufferSize === %d", mBufferSize);

    m_pBuffer = static_cast<uint8_t *>(malloc(mBufferSize));
    if (m_pBuffer == nullptr) {
        LOGE("malloc buffer error");
        m_pMtkConfig->DeInit();
        return -1;
    }

    mBytesPerFrame = m_pMtkConfig->pcmFrames2Bytes(1);
    LOGD("mBytesPerFrame === %d", mBytesPerFrame);
    mFramesRead = 0;
    mTotalFramesRead = 0;
    TvThread::Run(TvThread::REPEAT);
    m_bIsMicThreadRunning = true;
    return MI_SUCCESS;
}

int MicThread::DeInit() {
    TvThread::ExitAndJoin();
    return MI_SUCCESS;
}

void MicThread::Run(const void *arg) {

    memset(m_pBuffer,0,mBufferSize);
    mFramesRead = m_pMtkConfig->readMic(m_pBuffer,mBufferSize);
    mTotalFramesRead += mBufferSize;
    m_pSaveWav->writeToFile(m_pBuffer,1,mBufferSize);
}

void MicThread::OnTvMWThreadExit(TvThread *pTvMWThread) {

    LOGD("mTotalFramesRead  == %d",mTotalFramesRead);

    if (m_pMtkConfig == nullptr){
        m_bIsMicThreadRunning = false;
        return;
    }
    if (m_pMtkConfig->DeInit() != MI_SUCCESS){
        m_bIsMicThreadRunning = false;
        return;
    }

    if (m_pMtkConfig != nullptr){
        delete m_pMtkConfig;
        m_pMtkConfig = nullptr;
    }

    if (m_pSaveWav) {
        m_pSaveWav->saveWav2File(mTotalFramesRead);
        m_pSaveWav->closeFile();
        delete m_pSaveWav;
        m_pSaveWav = nullptr;
    }
    if (m_pBuffer)
        free(m_pBuffer);
    m_bIsMicThreadRunning = false;
    LOGD("OnTvMWThreadExit Success!");
}

bool MicThread::isMicThreadRunning() {
    return m_bIsMicThreadRunning;
}